home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / hack / 1 / src / makemon.c < prev    next >
Encoding:
C/C++ Source or Header  |  1985-07-26  |  4.4 KB  |  199 lines

  1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  2. /* hack.makemon.c - version 1.0.2 */
  3.  
  4. #include    "hack.h"
  5. extern char fut_geno[];
  6. extern char *index();
  7. extern struct obj *mkobj_at();
  8. struct monst zeromonst;
  9.  
  10. /*
  11.  * called with [x,y] = coordinates;
  12.  *    [0,0] means anyplace
  13.  *    [u.ux,u.uy] means: call mnexto (if !in_mklev)
  14.  *
  15.  *    In case we make an Orc or killer bee, we make an entire horde (swarm);
  16.  *    note that in this case we return only one of them (the one at [x,y]).
  17.  */
  18. struct monst *
  19. makemon(ptr,x,y)
  20. register struct permonst *ptr;
  21. {
  22.     register struct monst *mtmp;
  23.     register tmp, ct;
  24.     boolean anything = (!ptr);
  25.  
  26.     if(x != 0 || y != 0) if(m_at(x,y)) return((struct monst *) 0);
  27.     if(ptr){
  28.         if(index(fut_geno, ptr->mlet)) return((struct monst *) 0);
  29.     } else {
  30.         ct = CMNUM - strlen(fut_geno);
  31.         if(index(fut_geno, 'm')) ct++;  /* make only 1 minotaur */
  32.         if(index(fut_geno, '@')) ct++;
  33.         if(ct <= 0) return(0);           /* no more monsters! */
  34.         tmp = rn2(ct*dlevel/24 + 7);
  35.         if(tmp < dlevel - 4) tmp = rn2(ct*dlevel/24 + 12);
  36.         if(tmp >= ct) tmp = rn1(ct - ct/2, ct/2);
  37.         for(ct = 0; ct < CMNUM; ct++){
  38.             ptr = &mons[ct];
  39.             if(index(fut_geno, ptr->mlet))
  40.                 continue;
  41.             if(!tmp--) goto gotmon;
  42.         }
  43.         panic("makemon?");
  44.     }
  45. gotmon:
  46.     mtmp = newmonst(ptr->pxlth);
  47.     *mtmp = zeromonst;    /* clear all entries in structure */
  48.     for(ct = 0; ct < ptr->pxlth; ct++)
  49.         ((char *) &(mtmp->mextra[0]))[ct] = 0;
  50.     mtmp->nmon = fmon;
  51.     fmon = mtmp;
  52.     mtmp->m_id = flags.ident++;
  53.     mtmp->data = ptr;
  54.     mtmp->mxlth = ptr->pxlth;
  55.     if(ptr->mlet == 'D') mtmp->mhpmax = mtmp->mhp = 80;
  56.     else if(!ptr->mlevel) mtmp->mhpmax = mtmp->mhp = rnd(4);
  57.     else mtmp->mhpmax = mtmp->mhp = d(ptr->mlevel, 8);
  58.     mtmp->mx = x;
  59.     mtmp->my = y;
  60.     mtmp->mcansee = 1;
  61.     if(ptr->mlet == 'M'){
  62.         mtmp->mimic = 1;
  63.         mtmp->mappearance = ']';
  64.     }
  65.     { extern boolean in_mklev;
  66.     if(!in_mklev) {
  67.         if(x == u.ux && y == u.uy && ptr->mlet != ' ')
  68.             mnexto(mtmp);
  69.         if(x == 0 && y == 0)
  70.             rloc(mtmp);
  71.     }}
  72.     if(ptr->mlet == 's' || ptr->mlet == 'S') {
  73.         mtmp->mhide = mtmp->mundetected = 1;
  74.         if(in_mklev)
  75.         if(mtmp->mx && mtmp->my)
  76.             (void) mkobj_at(0, mtmp->mx, mtmp->my);
  77.     }
  78.     if(ptr->mlet == ':') {
  79.         mtmp->cham = 1;
  80.         (void) newcham(mtmp, &mons[dlevel+14+rn2(CMNUM-14-dlevel)]);
  81.     }
  82.     if(ptr->mlet == 'I' || ptr->mlet == ';')
  83.         mtmp->minvis = 1;
  84.     if(ptr->mlet == 'L' || ptr->mlet == 'N'
  85.         || (in_mklev && index("&w;", ptr->mlet) && rn2(5))
  86.     ) mtmp->msleep = 1;
  87.  
  88. #ifndef NOWORM
  89.     if(ptr->mlet == 'w' && getwn(mtmp))
  90.         initworm(mtmp);
  91. #endif NOWORM
  92.  
  93.     if(anything) if(ptr->mlet == 'O' || ptr->mlet == 'k') {
  94.         coord enexto();
  95.         coord mm;
  96.         register int cnt = rnd(10);
  97.         mm.x = x;
  98.         mm.y = y;
  99.         while(cnt--) {
  100.             mm = enexto(mm.x, mm.y);
  101.             (void) makemon(ptr, mm.x, mm.y);
  102.         }
  103.     }
  104.  
  105.     return(mtmp);
  106. }
  107.  
  108. coord
  109. enexto(xx,yy)
  110. register xchar xx,yy;
  111. {
  112.     register xchar x,y;
  113.     coord foo[15], *tfoo;
  114.     int range;
  115.  
  116.     tfoo = foo;
  117.     range = 1;
  118.     do {    /* full kludge action. */
  119.         for(x = xx-range; x <= xx+range; x++)
  120.             if(goodpos(x, yy-range)) {
  121.                 tfoo->x = x;
  122.                 tfoo++->y = yy-range;
  123.                 if(tfoo == &foo[15]) goto foofull;
  124.             }
  125.         for(x = xx-range; x <= xx+range; x++)
  126.             if(goodpos(x,yy+range)) {
  127.                 tfoo->x = x;
  128.                 tfoo++->y = yy+range;
  129.                 if(tfoo == &foo[15]) goto foofull;
  130.             }
  131.         for(y = yy+1-range; y < yy+range; y++)
  132.             if(goodpos(xx-range,y)) {
  133.                 tfoo->x = xx-range;
  134.                 tfoo++->y = y;
  135.                 if(tfoo == &foo[15]) goto foofull;
  136.             }
  137.         for(y = yy+1-range; y < yy+range; y++)
  138.             if(goodpos(xx+range,y)) {
  139.                 tfoo->x = xx+range;
  140.                 tfoo++->y = y;
  141.                 if(tfoo == &foo[15]) goto foofull;
  142.             }
  143.         range++;
  144.     } while(tfoo == foo);
  145. foofull:
  146.     return( foo[rn2(tfoo-foo)] );
  147. }
  148.  
  149. goodpos(x,y)    /* used only in mnexto and rloc */
  150. {
  151.     return(
  152.     ! (x < 1 || x > COLNO-2 || y < 1 || y > ROWNO-2 ||
  153.        m_at(x,y) || !ACCESSIBLE(levl[x][y].typ)
  154.        || (x == u.ux && y == u.uy)
  155.        || sobj_at(ENORMOUS_ROCK, x, y)
  156.     ));
  157. }
  158.  
  159. rloc(mtmp)
  160. struct monst *mtmp;
  161. {
  162.     register tx,ty;
  163.     register char ch = mtmp->data->mlet;
  164.  
  165. #ifndef NOWORM
  166.     if(ch == 'w' && mtmp->mx) return;    /* do not relocate worms */
  167. #endif NOWORM
  168.     do {
  169.         tx = rn1(COLNO-3,2);
  170.         ty = rn2(ROWNO);
  171.     } while(!goodpos(tx,ty));
  172.     mtmp->mx = tx;
  173.     mtmp->my = ty;
  174.     if(u.ustuck == mtmp){
  175.         if(u.uswallow) {
  176.             u.ux = tx;
  177.             u.uy = ty;
  178.             docrt();
  179.         } else    u.ustuck = 0;
  180.     }
  181.     pmon(mtmp);
  182. }
  183.  
  184. struct monst *
  185. mkmon_at(let,x,y)
  186. char let;
  187. register int x,y;
  188. {
  189.     register int ct;
  190.     register struct permonst *ptr;
  191.  
  192.     for(ct = 0; ct < CMNUM; ct++) {
  193.         ptr = &mons[ct];
  194.         if(ptr->mlet == let)
  195.             return(makemon(ptr,x,y));
  196.     }
  197.     return(0);
  198. }
  199.